home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d10
/
ps1410.arc
/
CAL5.BAS
< prev
next >
Wrap
BASIC Source File
|
1990-10-31
|
68KB
|
1,844 lines
'=========================================================================
' Personal Calendar (PC) Program
' Copyright (c) 1985-1990, Paul Munoz-Colman. All Rights Reserved.
' Version 14.10
' 31 Oct 1990
' Shareware $25
'=========================================================================
' DOS File CAL5.BAS
' Independently Compiled Subprograms Which Are Linked With CAL1.BAS
'=========================================================================
' Written For IBM PCs & Compatibles Under MS DOS 3.30 on a Northgate 486
' Compiled By Microsoft Professional BASIC 7.10, Linker Version 5.10
'=========================================================================
' Note -- Tabs in the source file are in positions 6,11,16,21,26,...
'=========================================================================
' $INCLUDE: 'cal1.bi'
'=========================================================================
' Subprogram List in the Order of Appearance in this File
' (compiled WITHOUT error handling--no /E or /X)
'-------------------------------------------------------------------------
' Name Purpose
' --------------------------- ---------------------------------------
' PoppedOverCheck Check to See Whether Popped Over DOS
' PrepareforError Clear and Place for Error Message
' PrepareforFatal Prepare for QuickBASIC Error Message
' PrepareforMessage Clear and Place for Info Message
' PrintCalendar Display Three Months of Calendars
' PrintCopy Print or Copy Appointments to ASCII File
' ProcessAlarm Update Event and History Upon Alarm
' PutApptRecord (Pointer) Put Records in Appt File (Blank if 0)
' QuickSort (SortLow, SortHigh) Sort Alarm Table Routine
' QuitLine Ctl-ESC to Quit Instruction
' QuitLineDelete Ctl-ESC to Quit Instruction
' Fn RandInt (Lower, Upper) Random integer from lower to upper
' ReadCalauto Read Auto Start CALAUTO.DAT File
' ReadCalDOS Read DOS Command CALDOS.DAT File
' ReadCalexcl Read Exclusion CALEXCL.DAT File
' ReadCalfig Read Colors CALFIG.DAT File
' ReadCalmusic Read CALMUSIC.DAT File
' ReadCalres Read CALRES.DAT File
' RefreshEventsNotes Display Clock Screen Footer
' RepackApptRecord Build Event Record From Fields
' RestoreCalKeyState Restore State of Ins,Caps,Num,Scrl
' RestoreDOSKeyState Restore State of DOS Ins,Caps,Num,Scrl
' ReturnLine Enter Instruction
' ReturnLineDelete Enter Instruction Blank Out
' SaveCurrentDirectory (EntryPoint)
' Get Program or User Directory
' SaveDOSKeyState Save State of DOS Ins,Caps,Num,Scrl
' ScreenBottoms Esc, Quit, and Return Instructions
' ScreenBottomsDelete Esc, Quit, and Return Instructions Blank
' SequenceEventsTable Resort Events Listing
' SetArrays Set Array Sizes Based Upon Event File
' SetColors Color Choice Menus
' SetCurrentDirectory (EntryPoint)
' Change to Current or User Directory
'=========================================================================
SUB PoppedOverCheck STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 52
' Check to see Whether Program Is Popped Up Over the DOS Prompt or
' Over another Program. Can't remove from memory or SrResidentShell
' Unless Popped Up Over DOS
PoppedUpOverProgram = No
PoppedUpOverDOS = No
IF MemoryResident THEN
IF SrOverDOS% THEN '** SRP4
PoppedUpOverDOS = Yes '** SRP4
ELSE '** SRP4
PoppedUpOverProgram = Yes '** SRP4
END IF '** SRP4
END IF
Subnum = SubnumSave
END SUB
'=========================================================================
SUB PrepareforError STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 53
CALL ClearScreenNormal(N1)
CALL MajorBeeper
CALL Kolors(N14)
CALL BlankError
Subnum = SubnumSave
END SUB
'=========================================================================
SUB PrepareforFatal STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 54
CALL ClearScreenNormal(N1)
CALL MajorBeeper
CALL Kolors(N14)
CALL BlankFatal
Subnum = SubnumSave
END SUB
'=========================================================================
SUB PrepareforMessage STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 55
CALL MinorBeeper
CALL Kolors(N14)
CALL BlankError
Subnum = SubnumSave
END SUB
'=========================================================================
SUB PrintCalendar STATIC
'=========================================================================
' Display Calendars (PrintCalendar)
DEFINT A-Z
SubnumSave = Subnum
Subnum = 56
'-------------------------------------------------------------------------
' If Printing Report, Make Two Passes, One to Generate Calendars, and
' Another To Return Them To The CalendarDate$ In Memory, If Necessary
PrintPass$ = False$
IF PrintingReport THEN
PassEntry:
IF PrintPass$ = "2" THEN GOTO ExitPoint
IF PrintPass$ = "1" THEN
IF TodaysDate$ = HoldWhilePrinting$ OR FirstTimeClock = Yes THEN
GOTO ExitPoint
END IF
PrintPass$ = "2" ' Restore Calendar Arrays to
CalendarDate$ = HoldWhilePrinting$ ' Whatever They Were
END IF
IF PrintPass$ = False$ THEN
PrintPass$ = "1"
HoldWhilePrinting$ = MemoryDate$
CalendarDate$ = TodaysDate$
END IF
END IF
'-------------------------------------------------------------------------
' If Calendars In Memory, Don't Recompute
' Calendars In Memory--Check If Printing or Timer In Case Resequenced
IF MemoryDate$ = CalendarDate$ THEN 'Wrong Date Recomputes
' Right Date/Printing Skips
IF PrintPass$ = "1" THEN GOTO ShowCalendars
' Right Date/Time Skips
IF MemoryTime! = TimerSave! THEN GOTO ShowCalendars
END IF
'-------------------------------------------------------------------------
' Not in Memory, So Recompute Calendar Values
MemoryTime! = TIMER
TimerSave! = MemoryTime!
MemoryDate$ = CalendarDate$
CalendarYear = VAL(MID$(CalendarDate$, N1, N4))
CalendarMonth = VAL(MID$(CalendarDate$, N5, N2))
CalendarDay = VAL(MID$(CalendarDate$, N7, N2))
CalendarMonths(N2) = CalendarMonth
CalendarYears(N2) = CalendarYear
'-------------------------------------------------------------------------
' Months And Years For Prior and Next Calendar
SELECT CASE CalendarMonth
'--------------------------------------------------------------------
CASE 1 ' Middle Month is January
CalendarMonths(N1) = N12
IF CalendarYear > N0 THEN
CalendarYears(N1) = CalendarYear - N1
ELSE
CalendarYears(N1) = 9999
END IF
CalendarMonths(N3) = CalendarMonth + N1
CalendarYears(N3) = CalendarYear
'--------------------------------------------------------------------
CASE 2 TO N11 ' Middle Month is February to November
CalendarMonths(N1) = CalendarMonth - N1
CalendarYears(N1) = CalendarYear
CalendarMonths(N3) = CalendarMonth + N1
CalendarYears(N3) = CalendarYear
'--------------------------------------------------------------------
CASE N12 ' Middle Month is December
CalendarMonths(N1) = CalendarMonth - N1
CalendarYears(N1) = CalendarYear
CalendarMonths(N3) = N1
IF CalendarYear < 9999 THEN
CalendarYears(N3) = CalendarYear + N1
ELSE
CalendarYears(N3) = N0
END IF
'--------------------------------------------------------------------
END SELECT
'-------------------------------------------------------------------------
' Determine the First Week Day of Each Month
'-------------------------------------------------------------------------
FOR MonthIndex = N1 TO N3
CALL YearAdjust(CalendarYears(MonthIndex), AdjustedYear$)
DatetoIndex$ = ZeroFill$(AdjustedYear$ + _
RIGHT$(STR$(CalendarMonths(MonthIndex)), N2) + "01")
CALL DayDate(DatetoIndex$)
FirstDays(MonthIndex) = IndexedDay
NEXT
'-------------------------------------------------------------------------
CalendarImage(N1) = Blank80$
' Store And Display
'-------------------------------------------------------------------------
FOR MonthIndex = N1 TO N3
'--------------------------------------------------------------------
IF MonthIndex = N2 THEN ColumnOffset = N17 ELSE ColumnOffset = N22
' Year Of Middle Month-Centered
'--------------------------------------------------------------------
MonthnameStart = CalendarColumns(MonthIndex) + (ColumnOffset - _
LEN(MonthNames$(CalendarMonths(MonthIndex)))) \ N2
MonthnameLength = LEN(MonthNames$(CalendarMonths(MonthIndex)))
' Month Name
'--------------------------------------------------------------------
IF MonthIndex <> N2 THEN
CALL Myd2(CalendarImage(N1), MonthnameStart, MonthnameLength, _
(MonthNames$(CalendarMonths(MonthIndex))))
END IF
MonthnameStart = CalendarColumns(MonthIndex) + (ColumnOffset - _
LEN(MonthNames$(CalendarMonths(MonthIndex)))) \ N2
CALL YearAdjust(CalendarYears(N2), AdjustedYear$)
AdjustedYear$ = ZeroFill$(AdjustedYear$)
MonthnameLength = LEN(MonthNames$(CalendarMonths(MonthIndex)) + _
Blank1$ + AdjustedYear$)
IF MonthIndex = N2 THEN
CALL Myd2(CalendarImage(N1), MonthnameStart, MonthnameLength, _
(MonthNames$(CalendarMonths(MonthIndex)) + Blank1$ + AdjustedYear$))
END IF
' Month Name,Year
'--------------------------------------------------------------------
NEXT
'-------------------------------------------------------------------------
CalendarImage(N2) = Blank80$
' Day Labels
'-------------------------------------------------------------------------
FOR MonthIndex = N1 TO N3
FOR DayPlacement = N1 TO N7
CALL Myd2(CalendarImage(N2), N1 + _
CalendarColumns(MonthIndex) + N3 * (DayPlacement - N1), _
N2, DayNames$(DayPlacement))
NEXT DayPlacement
NEXT MonthIndex
'-------------------------------------------------------------------------
FOR I = N1 TO N6
CalendarImage(N2 + I) = Blank80$
NEXT
'-------------------------------------------------------------------------
IF ApptFile THEN
AlarmPointer = N1
AlarmsAvailable = Yes
LightTable = N1
FOR I = N1 TO N2 * NumberofEvents
LightDay(I) = N0
NEXT
END IF
'-------------------------------------------------------------------------
FOR MonthIndex = N1 TO N3
CALL KeyStuff(KeyStatus)
' Days
LeapReturn = Leap(CalendarYears(MonthIndex))
IF CalendarMonths(MonthIndex) = N2 AND LeapReturn = N1 THEN
EndingDay = 29
ELSE
EndingDay = MonthLength(CalendarMonths(MonthIndex))
END IF
' Leap Year Goes To 29
FirstDayOfWeek = FirstDays(MonthIndex)
' Starting Day
'--------------------------------------------------------------------
FOR WhichDay = N1 TO EndingDay
'---------------------------------------------------------------
WhichRow = (FirstDayOfWeek - N1) \ N7
' Line To Display The Day On
DayOfWeekPosition = FirstDayOfWeek MOD N7
IF DayOfWeekPosition = N0 THEN DayOfWeekPosition = N7
DayOfWeekPosition = DayOfWeekPosition * N3 - N3
DayToShow$ = BlankFill$(RIGHT$(STR$(WhichDay), N2))
'---------------------------------------------------------------
' Hor Offset
CALL Myd2(CalendarImage(N3 + WhichRow), N1 + _
CalendarColumns(MonthIndex) + DayOfWeekPosition, _
N2, DayToShow$)
'---------------------------------------------------------------
' Store The Day In The Display Line
IF ApptFile AND AlarmsAvailable THEN
SELECT CASE Alarms(AlarmPointer).Alarm
CASE IS = 0#
AlarmsAvailable = No
CASE ELSE
AlarmDayStore:
DaycalTest& = CalendarYears(MonthIndex) * 10000& _
+ CalendarMonths(MonthIndex) * 100& + WhichDay
DaytableTest& = _
FIX(Alarms(AlarmPointer).Alarm / 10000&)
SELECT CASE DaytableTest&
CASE IS < DaycalTest&
AlarmPointer = AlarmPointer + N1
IF AlarmPointer <= NumberofEvents THEN
GOTO AlarmDayStore
END IF
AlarmsAvailable = No
CASE IS = DaycalTest&
LightDay(LightTable) = N1 + WhichRow
LightDay(LightTable + N1) = _
CalendarColumns(MonthIndex) + _
DayOfWeekPosition
LightTable = LightTable + N2
END SELECT
END SELECT
END IF
'---------------------------------------------------------------
IF MonthIndex = N2 AND WhichDay = CalendarDay THEN
HilitRow = WhichRow + N2
' Hilit Day
HilitColumn = CalendarColumns(MonthIndex) + _
DayOfWeekPosition
HilitDay$ = DayToShow$
TodayBright = N0
IF ApptFile AND ((NormalCalendars AND OverdueCount) OR _
(DaycalTest& <> 0& AND _
DaycalTest& = DaytableTest&)) THEN
TodayBright = N1
END IF
END IF
FirstDayOfWeek = FirstDayOfWeek + N1
NEXT WhichDay
'--------------------------------------------------------------------
IF WhichDay = 29 AND LeapReturn = N1 THEN
WhichRow = (FirstDayOfWeek - N1) \ N7
' Vertical Offset For Leap Year Day
DayOfWeekPosition = FirstDayOfWeek MOD N7
IF DayOfWeekPosition = N0 THEN DayOfWeekPosition = N7
DayOfWeekPosition = DayOfWeekPosition * N3 - N3
' Hor Offset
CALL Myd2(CalendarImage(N3 + WhichRow), N1 + _
CalendarColumns(MonthIndex) + DayOfWeekPosition, N3, "29")
END IF
NEXT MonthIndex
'-------------------------------------------------------------------------
' Recompute Finished
'-------------------------------------------------------------------------
' Display Calendars
ShowCalendars:
IF PrintPass$ = "1" THEN ' Calendars From Print or Copy
FOR I = N1 TO N8
CALL KeyStuff(KeyStatus)
IF PrintorCopy$ = "p" AND CalendarImage(I) <> Blank80$ THEN
CALL LprintString(SPACE$(N5) + _
LEFT$(CalendarImage(I), N70), N0)
IF LprintTerminate THEN GOTO ExitPoint
END IF
IF PrintorCopy$ = "w" AND CalendarImage(I) <> Blank80$ THEN
PRINT #FilenumCopy, SPACE$(N5); LEFT$(CalendarImage(I), N70)
END IF
NEXT
END IF
IF PrintingReport THEN GOTO PassEntry
CSRow = CalendarStartRow + N1
CSColumn = CalendarStartColumn + N1
CSColumn2 = CSColumn + CalendarColumns(N2)
ShowString$ = LEFT$(CalendarImage(N1), N70)
CALL ShowIt(N4, CSRow, CSColumn, ShowString$)
ShowString$ = MID$(CalendarImage(N1), N1 + CalendarColumns(N2), N20)
CALL ShowIt(N11, N0, CSColumn2, ShowString$)
ShowString$ = LEFT$(CalendarImage(N2), N70)
CALL ShowIt(N4, Nm1, CSColumn, ShowString$)
'-------------------------------------------------------------------------
' Display Calendar Lines On Screen and Highlight If Called For
FOR CalendarRow = N1 TO N6
CALL KeyStuff(KeyStatus)
CSRow = CalendarStartRow + N2 + CalendarRow
CSColumn = CalendarStartColumn + N1
ShowString$ = LEFT$(CalendarImage(N2 + CalendarRow), N70)
CALL ShowIt(N4, CSRow, CSColumn, ShowString$)
IF ApptFile THEN
FOR LightTable = N1 TO Nm1 + N2 * NumberofEvents STEP N2
IF LightDay(LightTable) = N0 OR _
LightDay(LightTable) > CalendarRow THEN
EXIT FOR
END IF
YSave = LightDay(LightTable) 'Array Row
CSRow = YSave + CalendarStartRow + N2 'Screen Row
XSave = LightDay(LightTable + N1) 'Array Column
CSColumn = XSave + CalendarStartColumn + N1 ' Screen Column
ShowString$ = MID$(CalendarImage(N2 + YSave), _
N1 + XSave, N2)
CALL ShowIt(N11, CSRow, CSColumn, ShowString$)
NEXT LightTable
END IF
NEXT CalendarRow
'-------------------------------------------------------------------------
CSRow = CalendarStartRow + HilitRow + N1
CSColumn = CalendarStartColumn + HilitColumn + N1
CALL ShowErase(N4, CSRow, CSColumn, N3, Blank0$)
IF NOT ApptFile OR TodayBright = N0 THEN
CALL Kolors(N7)
ELSE
CALL Kolors(N14)
END IF
CALL ShowIt(N0, N0, N0, HilitDay$)
CALL DayDate(CalendarDate$)
J = IndexedDay
CSRow = CalendarStartRow + N2
ShowString$ = LEFT$(DayNames$(J), N2)
CALL ShowIt(N0, CSRow, ScreenColumn, ShowString$)
' Hilit Today's Date and Day of the Week
RedisplayCalendars = No
ExitPoint:
Subnum = SubnumSave
END SUB
'=========================================================================
SUB PrintCopy STATIC
'=========================================================================
' Print or Copy Appointment File To DOS File
DEFINT A-Z
SubnumSave = Subnum
Subnum = 57
'-------------------------------------------------------------------------
PrintingReport = Yes
IF ClockScreenPrint THEN GOTO StartPrint
'--------------------------------------------------------------------
' Print/Copy File
DirectReturn = Yes
' Clear Line 25
CALL ShowErase(N6, N25, N1, N80, Blank0$)
CALL DisplayApptFilename
IF PrintorCopy$ <> "p" THEN
'---------------------------------------------------------------
CopyFilename$ = SPACE$(N12)
CALL Myd2(CopyFilename$, N1, LEN(ApptFilename$), ApptFilename$)
CALL Myd2(CopyFilename$, InString(CopyFilename$, Blank1$), _
N4, ".asc")
CALL ControlledInput(N25, N28, N25, N8, N12, _
"Name of ASCII File", CopyFilename$, N0, N1, N1, N1)
IF Keystroke$ = CHR$(Esc) THEN
CALL ClearScreenNormal(N1)
GOTO AllOver
END IF
'---------------------------------------------------------------
CLOSE FilenumCopy
OPEN "O", FilenumCopy, CopyFilename$, N80
ELSE
StartPrint:
CALL InitPrinter
If LprintTerminate THEN GOTO TerminatePrint
END IF
IF NOT ClockScreenPrint THEN
CALL Kolors(N14)
CALL BlankError
IF PrintorCopy$ = "p" THEN
CALL ShowIt(N0, N0, N0, "Printing Appointments")
ELSE
CALL ShowIt(N0, N0, N0, _
("Generating ASCII File " + CopyFilename$))
END IF
END IF
'-------------------------------------------------------------------------
CALL GetFilenameLength
DisplayFilename$ = LEFT$(ApptFilename$, FilenameLength)
GOSUB DoubleEqualLine
Buffer80$ = DayNames$(TodaysDay) + ", " + DATE$ + SPACE$(N2) + _
TIME$ + " " + DisplayFilename$ + _
"'s Appointment Calendar"
GOSUB PrintALine
'-------------------------------------------------------------------------
GOSUB DoubleEqualLine
CALL PrintCalendar ' Calendars Before Events
'-------------------------------------------------------------------------
GOSUB DoubleEqualLine
Buffer80$ = "Events (" + RIGHT$(STR$(EventsScheduled), N3) + ")"
GOSUB PrintALine
GOSUB DoubleEqualLine
'-------------------------------------------------------------------------
' Initialize Counter For Week Break Logic
PreviousIndexedDay = N0
FOR I = N1 TO NumberofEvents
WhichEvent = I
CALL ApptToMenu(N1)
CALL KeyStuff(KeyStatus)
IF CurrentEventRecord$ <> Blank80$ THEN
'----------------------------------------------------------------
' Write Events
' If No Week Break Wanted, Skip Break Logic
IF WeekBreak$ = True$ THEN
'----------------------------------------------------------
' Compute Whether Week Break Needed
' Get New Day of Week and Day Count
DatetoIndex$ = MID$(CurrentEventRecord$, N74, N2) + _
LEFT$(CurrentEventRecord$, N6)
CALL DayDate(DatetoIndex$)
CurrentIndexedDay = IndexedDay
CurrentCountedDay& = CountedDay&
'----------------------------------------------------------
' If First Time Through, Initialize Comparison Holders
IF PreviousIndexedDay = N0 THEN
GOSUB SaveDayCounts ' Save Day Counts
'-----------------------------------------------------
' If New Day of Week More Than 7 Beyond Old,
' Or Not Later In Week
ELSEIF CurrentIndexedDay < PreviousIndexedDay OR _
(CurrentCountedDay& - _
PreviousCountedDay&) >= 7& THEN
GOSUB SingleEqualLine ' Generate Week Breaker
GOSUB SaveDayCounts ' Save Day Counts
END IF
'----------------------------------------------------------
END IF
' Generate Event Line
Buffer80$ = CurrentEventLine$
GOSUB PrintALine
END IF
NEXT
'-------------------------------------------------------------------------
IF InclNotes THEN
' Write Notes
GOSUB DoubleEqualLine
Buffer80$ = "Notes"
GOSUB PrintALine
GOSUB DoubleEqualLine
FOR I = N1 TO NumberofNotes
CALL KeyStuff(KeyStatus)
Pointer = StartingNote + I - N1
CALL GetApptRecord(Pointer)
Buffer80$ = ApptBuffer$
IF Buffer80$ <> Blank80$ THEN
IF PrintorCopy$ = "p" THEN ' Don't number on a copy
CALL MhMidString(Buffer80$, N6%, N75%, _
ApptBuffer$, N1%)
MID$(Buffer80$, N1, N5) = SPACE$(N5)
MID$(Buffer80$, N1, N5) = STR$(I)
END IF
GOSUB PrintALine
END IF
NEXT
END IF
IF InclHistory THEN
' Write History
GOSUB DoubleEqualLine
Buffer80$ = "History (" + STR$(LOF(FilenumAppt) \ N80 - _
StartingHistory + N1) + ")"
GOSUB PrintALine
GOSUB DoubleEqualLine
FOR I = StartingHistory TO LOF(FilenumAppt) \ N80
CALL KeyStuff(KeyStatus)
CALL GetApptRecord(I)
Buffer80$ = ApptBuffer$
IF Buffer80$ <> Blank80$ THEN GOSUB PrintALine
NEXT
END IF
PrintingReport = No
IF NOT ClockScreenPrint THEN
CALL ClearScreenNormal(N1)
CALL Kolors(N14)
CALL BlankError
Menu1 = MainMenuLastEntry
IF PrintorCopy$ = "w" THEN
GOSUB DoubleEqualLine
CLOSE FilenumCopy
CALL ShowIt(N0, N0, N0, _
("Completed Generation of ASCII File " + CopyFilename$))
GOTO AllOver
END IF
END IF
CALL PageEject
LprintJobOver = Yes
CALL LprintString(Blank0$, N0)
If LprintTerminate THEN GOTO TerminatePrint
IF NOT ClockScreenPrint THEN
CALL BlankError
CALL ShowIt(N0, N0, N0, ("Completed Print Generation for " + _
ApptFilename$))
END IF
GOTO AllOver
DoubleEqualLine:
Buffer80$ = Strng$(N80, 61) 'Main Separator (equals)
GOSUB PrintALine
RETURN
SingleEqualLine:
Buffer80$ = Strng$(N80, N45) 'Week Breaker (hyphens)
GOSUB PrintALine
RETURN
PrintALine:
CALL KeyStuff(KeyStatus)
Buffer80$ = RTRIM$(Buffer80$)
IF PrintorCopy$ = "p" THEN
CALL LprintString(Buffer80$, N0) ' Generate Print
TerminatePrint:
IF LprintTerminate THEN
LprintTerminate = No
PrintPass$ = False$
PrintingReport = No
IF NOT ClockScreenPrint THEN
CALL Kolors(N14)
CALL BlankError
CALL ShowIt(N0, N0, N0, _
"Print Generation Terminated by Request")
CALL Kolors(N6)
CALL ClearLast3
END IF
GOTO AllOver
END IF
ELSE
PRINT #FilenumCopy, Buffer80$ ' Generate Record
END IF
RETURN
' Save Day Counts for Comparison
SaveDayCounts:
PreviousIndexedDay = CurrentIndexedDay
PreviousCountedDay& = CurrentCountedDay&
RETURN
AllOver:
ClockScreenPrint = No
LprintTerminate = No
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ProcessAlarm STATIC
'=========================================================================
' Alarm Ringing, Reschedule Recurring Events, Resequence Table &
' Fill Overdue Table With Late Events
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 58
EventTableStable = No
OPEN "R", #FilenumOverdue, ApptFilenameOverdue$, N80
FIELD #FilenumOverdue, N80 AS OverdueBuffer$
FOR AlarmTableIndex = N1 TO NumberofEvents
CALL KeyStuff(KeyStatus)
'--------------------------------------------------------------------
' Flag for Rescheduling Bi/Multi/Weeklies or Special Monthlies
Rescheduling = No
' Check Each Event For Lateness -- Not Null and Overdue
IF Alarms(AlarmTableIndex).Alarm <> 0# AND _
Alarms(AlarmTableIndex).Alarm <= CurrentDateTime# THEN
CALL ShowErase(N14, N25, N1, N80, (SPACE$(N19) + _
"Please Wait--Checking Overdue Event" + STR$(AlarmTableIndex) + SPACE$(N4)))
'---------------------------------------------------------------
' Late Event To End of Overdue Table, Alarm Entry Gets Cleared
Alarms(AlarmTableIndex).Alarm = 0#
OverdueCount = LOF(FilenumOverdue)\N80 + N1
WhichEvent = AlarmTableIndex
CALL ApptToMenu(N1)
CALL MhLset(OverdueBuffer$, CurrentEventLine$)
PUT #FilenumOverdue, OverdueCount
'---------------------------------------------------------------
' If Entry Is Not Null, Then Write It To History
IF CurrentEventLine$ <> Blank80$ AND _
CurrentEventLine$ <> NullEvent$ THEN
EventtoHistory = Yes
HistoryBuffer$ = CurrentEventLine$
CALL WritetoHistory
END IF
'---------------------------------------------------------------
' If Entry Is Daily, Bi/Multi/Weekly, Monthly, Quarter/Yearly
' Then Reschedule It
LimitedsLeft = VAL(MID$(CurrentEventRecord$, N68, N2))
IF MID$(CurrentEventRecord$, N70, N1) = Blank1$ OR _
LimitedsLeft = N1 THEN
'----------------------------------------------------------
' If Entry Is One-Time or Last Recurring, Blank It Out
CurrentEventRecord$ = Blank80$
CurrentEventLine$ = Blank80$
ELSE
' Recurring With Last Time Blanks Out
'----------------------------------------------------------
' Decrement The Recurring Item Count if There
IF LimitedsLeft > N0 THEN
CALL Myd2(CurrentEventRecord$, N68, N2, _
(RIGHT$(STR$(LimitedsLeft - N1), N2)))
END IF
'----------------------------------------------------------
' Rebuild The Menu Entry For That Item
' And Rewrite Event Record
WhichEvent = AlarmTableIndex 'On 2 or more or
CALL UnpackApptRecord ' unlimited
CALL CombineDateTime
Rescheduling = Yes
CALL ValidateEventDate
CALL RepackApptRecord
CALL BuildMenuLine
END IF
CALL MhLset(ApptBuffer$, CurrentEventRecord$)
CALL PutApptRecord(N1 + AlarmTableIndex)
END IF
NEXT
CLOSE #FilenumOverdue
'-------------------------------------------------------------------------
' Resequence The Event Table
CALL SequenceEventsTable
'-------------------------------------------------------------------------
' Reprint Calendars, Notes and Events On Display
CALL PrintCalendar
CALL RefreshEventsNotes
Subnum = SubnumSave
END SUB
'=========================================================================
SUB PutApptRecord (Pointer) STATIC
'=========================================================================
' Put a Record To the Appointment File
' If a Null String Then Replace it by Blanks
DEFINT A-Z
SubnumSave = Subnum
Subnum = 59
IF NOT ApptFile THEN CALL OpenAppts
IF ApptBuffer$ = ZeroLine THEN ' Replace Null Record
CALL MhLset(ApptBuffer$, Blank80$)
END IF
PUT FilenumAppt, Pointer
Subnum = SubnumSave
END SUB
'========================================================================
DEFINT A-Z
SUB QuickSort (SortLow, SortHigh)
'========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 134
'=========================================================================
' QuickSort is adapted here from QB 4.50 Examples File SORTDEMO.BAS.
'=========================================================================
' QuickSort works by picking a random "pivot" element in Alarms, then
' moving every element that is bigger to one side of the pivot, and every
' element that is smaller to the other side. QuickSort is then called
' recursively with the two subdivisions created by the pivot. Once the
' number of elements in a subdivision reaches two, the recursive calls end
' and the array is sorted.
'=======================================================================
IF SortLow < SortHigh THEN
' Only two elements in this subdivision; swap them if they are out of
' order, then end recursive calls
IF SortHigh - SortLow = N1 THEN
IF Alarms(SortLow).Alarm > Alarms(SortHigh).Alarm THEN
SWAP Alarms(SortLow), Alarms(SortHigh)
END IF
ELSE
' Pick a pivot element at random, then move it to the end
RandIndex = RandInt(SortLow, SortHigh)
SWAP Alarms(SortHigh), Alarms(RandIndex)
Partition = Alarms(SortHigh).Alarm
DO
' Move in from both sides towards the pivot element:
I = SortLow
J = SortHigh
DO WHILE (I < J) AND (Alarms(I).Alarm <= Partition)
I = I + N1
LOOP
DO WHILE (J > I) AND (Alarms(J).Alarm >= Partition)
J = J - N1
LOOP
' If we haven't reached the pivot element, it means that two
' elements on either side are out of order, so swap them:
IF I < J THEN
SWAP Alarms(I), Alarms(J)
END IF
LOOP WHILE I < J
' Move the pivot element back to its proper place in the array:
SWAP Alarms(I), Alarms(SortHigh)
' Recursively call the QuickSort procedure (pass the smaller
' subdivision first to use less stack space):
IF (I - SortLow) < (SortHigh - I) THEN
QuickSort SortLow, I - N1
QuickSort I + N1, SortHigh
ELSE
QuickSort I + N1, SortHigh
QuickSort SortLow, I - N1
END IF
END IF
END IF
Subnum = SubnumSave
END SUB
'=========================================================================
SUB QuitLine STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 60
CALL QuitLineDelete
CALL ShowIt(N7, N25, N62, " Ctl-Esc ")
CALL ShowIt(N6, N0, Nm1, "Quit")
Subnum = SubnumSave
END SUB
'=========================================================================
SUB QuitLineDelete STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 61
CALL ShowErase(N6, N25, N62, N19, Blank0$)
Subnum = SubnumSave
END SUB
'=======================================================================
FUNCTION RandInt%(Lower%, Upper%) STATIC
'=======================================================================
' Returns a random integer greater than or equal to the Lower parameter
' and less than or equal to the Upper parameter.
'=======================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 135
RandInt = INT(RND * (Upper - Lower + N1)) + Lower
Subnum = SubnumSave
END FUNCTION
'=========================================================================
SUB ReadCalauto STATIC
'=========================================================================
' Read (Or Write) Automatic Startup File
DEFINT A-Z
SubnumSave = Subnum
Subnum = 110
UpdatingCalauto = No
IF NOT FileExist("calauto.dat") THEN
UpdatingCalauto = Yes
ELSE
ErrorSwitch = No
NewGuy = No ' File Exists, Read It
OPEN "I", #FilenumAuto, "calauto.dat"
CALL ReadCalautoGet ' with error handling in CAL1
IF ErrorSwitch THEN ' Check for short record
ErrorSwitch = No
UpdatingCalauto = Yes
END IF
END IF
CLOSE FilenumAuto
IF AutoMode$ = True$ AND NOT EarlyPopDownFailed THEN ' If attempt for TSR
AutostartMode = Yes ' fails before initialization
ELSE ' is complete, don't do
AutoStarted = No ' automatic startup
AutostartMode = No
EarlyPopDownFailed = No
END IF
IF AutostartMode THEN ' If okay then copy password
EnteredPassword$ = ApptPassword$
ELSE
ApptPassword$ = Blank8$
ApptFilename$ = Blank8$
END IF
' If a filename, let it alone, else set it to blanks with password
IF LEN(ApptFilename$) <> N8 THEN
ApptFilename$ = Blank8$
END IF
IF ApptFilename$ = Blank8$ THEN
ApptPassword$ = Blank8$
EnteredPassword$ = ApptPassword$
END IF
IF UpdatingCalauto THEN
CALL WriteCalauto 'Create or update auto start file
END IF
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ReadCalDOS STATIC
'=========================================================================
' Read (Or Write) DOS Command for F7
DEFINT A-Z
SubnumSave = Subnum
Subnum = 111
IF NOT FileExist("caldos.dat") THEN
CALL Snooze(0.7!)
CALL PrepareforMessage
CALL ShowIt(N0, N0, N0, _
" Created Prestored DOS Command File CALDOS.DAT")
ELSE
NewGuy = No
ErrorSwitch = No
OPEN "I", FilenumDOS, "caldos.dat"
CALL ReadCalDOSGet ' with error handling in main
IF NOT ErrorSwitch THEN
CLOSE FilenumDOS
EXIT SUB
END IF
END IF
DOSCommand$ = Blank80$
CLOSE FilenumDOS
CALL WriteCalDOS 'Create DOS Command File
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ReadCalexcl STATIC
'=========================================================================
' Read (or Write) Text Exclusions From History
DEFINT A-Z
SubnumSave = Subnum
Subnum = 112
IF NOT FileExist("calexcl.dat") THEN 'Read Entry (Write only if problems)
ErrorSwitch = Yes
CALL Snooze(0.7!)
CALL PrepareforMessage
CALL ShowIt(N0, N0, N0, _
" Created Event Exclusion From History File CALEXCL.DAT")
ELSE
NewGuy = No
ErrorSwitch = No
OPEN "I", FilenumExcl, "calexcl.dat"
CALL ReadCalexclGet ' with error handling in CAL1
CLOSE FilenumExcl
END IF
IF ErrorSwitch THEN CALL WriteCalexcl
ErrorSwitch = No
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ReadCalfig STATIC
'=========================================================================
' Read (Or Write) Color Choice File
DEFINT A-Z
SubnumSave = Subnum
Subnum = 113
Writefig = N0
UpdatingCalfig = No
IF NOT FileExist("calfig.dat") THEN 'Read Entry (Write only if problems)
UpdatingCalfig = Yes
Writefig = N1
ELSE
NewGuy = No
OPEN "I", FilenumFig, "calfig.dat"
ErrorSwitch = No
CALL ReadCalfigGet ' with error handling in CAL1
CLOSE FilenumFig
IF ErrorSwitch THEN ' Reading Past End Of File
UpdatingCalfig = Yes ' Those Variables Which Existed
Writefig = N1 ' Are Still In Memory -- The
ErrorSwitch = No
END IF ' Writing of CALFIG.DAT Will Fill
END IF ' in missing parameters
'====================================================================
IF Writefig = N1 THEN CALL WriteCalfig
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ReadCalmusic STATIC
'=========================================================================
' Read (Or Write) Music Choice File For Alarms and Chimes
DEFINT A-Z
SubnumSave = Subnum
Subnum = 114
IF NOT FileExist("calmusic.dat") THEN 'Read Entry (Write only if problems)
CALL Snooze(0.7!)
ErrorSwitch = Yes
CALL PrepareforMessage
CALL ShowIt(N0, N0, N0, _
" Created Music Choices File CALMUSIC.DAT")
ELSE
NewGuy = No
ErrorSwitch = No
OPEN "I", FilenumMusic, "calmusic.dat"
CALL ReadCalmusicGet ' with error handling in CAL1
CLOSE FilenumMusic
END IF
IF ErrorSwitch THEN
ErrorSwitch = No
IF LEN(Alarm$) = N0 THEN
Alarm$ = Blank80$
CALL Myd2 (Alarm$, N1, N58, "mb t255 ml o4 f9d9f9d9f9d" + _
"9f9d9f9d9 ms a9a9a9a9a9a9a9a9a9a9 t60 p2")
END IF
IF LEN(Chime$) = N0 THEN
Chime$ = Blank80$
CALL Myd2 (Chime$, N1, N32, _
"mb o2 ms l5 t70 bgad p2 dabg p2 t45")
END IF
IF LEN(Warning$) = N0 THEN
Warning$ = Blank80$
CALL Myd2 (Warning$, N1, N58, "mb t255 ml o2 f9d9f9d9f" + _
"9d9f9d9f9d9 ms a9a9a9a9a9a9a9a9a9a9 t60 p2")
END IF
CALL WriteCalmusic
END IF
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ReadCalres STATIC
'=========================================================================
' Read (Or Write) Stay-Res Options File
DEFINT A-Z
SubnumSave = Subnum
Subnum = 115
WriteRes = N0
UpdatingCalres = No
IF NOT FileExist("calres.dat") THEN 'Read Entry (Write only if problems)
WriteRes = N1
ELSE
NewGuy = No
ErrorSwitch = No
OPEN "I", FilenumRes, "calres.dat"
CALL ReadCalresGet ' with error handling in CAL1
CLOSE FilenumFig
IF ErrorSwitch THEN
WriteRes = N1
END IF
END IF
'--------------------------------------------------------------------
' Set Stay-Res Defaults and Internal Values as Needed
'====================================================================
' Fill In Whichever Options Are Missing
IF EverResident$ = True$ THEN
SrOptionsChosen = Yes
ELSE
SrOptionsChosen = No
EverResident$ = False$
END IF
IF UserPopDateTime$ = False$ THEN
AllowPopDateTime = No
ELSE
UserPopDateTime$ = True$
AllowPopDateTime = Yes
END IF
IF UseEMS$ = True$ THEN
SrDontUseEMS = No
ELSE
UseEMS$ = False$
SrDontUseEMS = Yes
END IF
IF NOT SrSnowCheck THEN
CALL SrNoSnow
END IF
IF UseDiskSwap$ = True$ THEN
SrDiskSwapping = Yes
ELSE
UseDiskSwap$ = False$
SrDiskSwapping = No
END IF
' Path for "swap" files is calendar's directory
IF SrSwapPath$ = Blank0$ OR NOT DirectoryExist(SrSwapPath$) THEN
WriteRes = Yes
SrSwapPath$ = ReturnPath$
END IF
IF SrKscanHot = N0 AND SrKshiftHot = N0 THEN
SrKscanHot = 103 ' Ctrl-Lshift-F10 is default hot key
SrKshiftHot = N6
END IF
' Get English Name of Defined Hot Key
CALL StayResKeyName
' Write File If Not Read Properly
IF WriteRes THEN
UpdatingCalres = Yes
CALL WriteCalres
END IF
ErrorSwitch = No
Subnum = SubnumSave
END SUB
'=========================================================================
SUB RefreshEventsNotes STATIC
'=========================================================================
' Refresh Event And Notes On Clock Display Page
DEFINT A-Z
SubnumSave = Subnum
Subnum = 63
FromOverduePage = No
SELECT CASE FooterSize
CASE 5, N9
FooterStartLine = N15
CASE 3, N4, 8
FooterStartLine = N16
CASE 6, 7
FooterStartLine = N17
END SELECT
' Refresh
IF FooterRecall THEN FooterAction$ = Blank1$ 'Footer Recall
IF NoteSize <> N0 AND FooterAction$ <> "e" THEN
' Notes
FOR I = N1 TO NoteSize
CALL KeyStuff(KeyStatus)
Pointer = I + CurrentNote + StartingNote - N2
CALL GetApptRecord(Pointer)
FooterRow = FooterStartLine + I + N1
IF FooterRow > N21 AND FooterRecall THEN
RefreshInstructions = Yes
FooterRecall = No
END IF
WindowLine$ = Blank80$
' Get Note Number and Right Justify It
EditLineLabel$ = STR$(CurrentNote - N1 + I)
LenTemp = LEN(EditLineLabel$) - N1 ' Less the leading space
IF LenTemp > N3 THEN LenTemp = N3 ' Only the right 3 chars
CALL Myd2(WindowLine$, N1, N3, (SPACE$(N3 - LenTemp) + _
RIGHT$(EditLineLabel$, LenTemp)))
CALL Myd2(WindowLine$, N6, N75, ApptBuffer$)
IF ColorCRT THEN
CALL Kolors(N9)
ELSE
CALL Kolors(N7)
END IF
CALL ShowIt(N0, FooterRow, N1, WindowLine$)
NEXT
END IF
IF OverdueCount THEN
IF OverdueCount > FooterSize - NoteSize THEN
CALL ShowOverduePage
FromOverduePage = Yes
GOTO ExitPoint2
END IF
IF SoundLevel > N2 AND NOT AlarmMusicPlayed THEN
CALL PlayAlarmWarning(N0)
END IF
AlarmMusicPlayed = Yes
OPEN "R", #FilenumOverdue, ApptFilenameOverdue$, N80
FIELD #FilenumOverdue, N80 AS OverdueBuffer$
FOR I = N1 TO OverdueCount
CALL KeyStuff(KeyStatus)
GET #FilenumOverdue, I
FooterRow = FooterStartLine + NoteSize + I + N1
IF FooterRow > N21 AND FooterRecall THEN
RefreshInstructions = Yes
FooterRecall = No
END IF
WindowLine$ = OverdueBuffer$
CALL ShowIt(N16, FooterRow, N1, WindowLine$)
NEXT
CLOSE #FilenumOverdue
END IF
IF OverdueCount <> FooterSize - NoteSize AND FooterAction$ <> False$ THEN
' Earliest Events
' Skip Blank
WindowSize = FooterSize - NoteSize - OverdueCount
FOR I = N1 TO WindowSize
WhichEvent = (CurrentEvent - N1 + I)
' Compute Event Table Index, Make Blink if a Warning
FooterRow = FooterStartLine + NoteSize + OverdueCount + I + N1
IF I = N1 THEN
EventWindowStart = FooterRow
END IF
IF FooterRow > N21 AND FooterRecall THEN
RefreshInstructions = Yes
FooterRecall = No
END IF
CALL ApptToMenu(N1)
EventWindow(I) = CurrentEventLine$
NEXT
FOR I = N1 to WindowSize
IF Pending = N0 THEN
CALL Kolors(N8)
ELSE
WhichEvent = (CurrentEvent - N1 + I)
IF PendingEvents(WhichEvent) = N0 THEN
CALL Kolors(N8)
ELSE
ColorForeground = Cl1b + N16
ColorBackground = Cl1f
CALL Kolors(N0)
END IF
END IF
CALL ShowIt(N0, (EventWindowStart + I - N1), _
N1, EventWindow(I))
NEXT
END IF
RedisplayNotesEvents = No
ExitPoint2:
Subnum = SubnumSave
END SUB
'=========================================================================
SUB RepackApptRecord STATIC
'=========================================================================
' Repack Appointment File Record From Individual Variables
DEFINT A-Z
SubnumSave = Subnum
Subnum = 64
CALL Myd2(EventYear1st2$, N1%, N2%, EventDate$)
CALL MhMidString(EventYear$, N1%, N2%, EventDate$, N3%)
CALL MhMidString(EventMonth$, N1%, N2%, EventDate$, N5%)
CALL MhMidString(EventDay$, N1%, N2%, EventDate$, N7%)
CALL Myd2(EventHour$, N1%, N2%, EventTime$)
CALL MhMidString(EventMinute$, N1%, N2%, EventTime$, N3%)
CALL Myd2(CurrentEventRecord$, N1%, N2%, EventYear$)
CALL Myd2(CurrentEventRecord$, N3%, N2%, EventMonth$)
CALL Myd2(CurrentEventRecord$, N5%, N2%, EventDay$)
CALL Myd2(CurrentEventRecord$, N7%, N2%, EventHour$)
CALL Myd2(CurrentEventRecord$, N9%, N2%, EventMinute$)
CALL Myd2(CurrentEventRecord$, N11%, TextSize%, EventText$)
CALL Myd2(CurrentEventRecord$, N68%, N2%, EventLimRepeat$)
CALL Myd2(CurrentEventRecord$, N70%, N3%, EventRepeat$)
CALL Myd2(CurrentEventRecord$, N74%, N2%, EventYear1st2$)
Subnum = SubnumSave
END SUB
'=========================================================================
SUB RestoreCalKeyState STATIC
'=========================================================================
' Restore Keys to Last State in This Program
DEFINT A-Z
SubnumSave = Subnum
Subnum = 66
' It is safe to use BASIC LOCATE here, because we're in the calendar
' and in text mode.
IF CursorState THEN ' Turn the Cal cursor on, if appropriate
' If the cursor is within limits, show it.
IF CursorRow > N0 AND CursorColumn > N0 AND _
CursorRow <= DisplayRows AND CursorColumn <= DisplayColumns THEN
LOCATE CursorRow, CursorColumn, CursorState, _
CursorStart, CursorStop
END IF
END IF
CALL MhSetKbStatus(Insrt%, Caps%, Num%, Scroll%) ' Restore Key States
Subnum = SubnumSave
END SUB
'=========================================================================
SUB RestoreDOSKeyState STATIC
'=========================================================================
' Restore DOS Keys to Original State
DEFINT A-Z
SubnumSave = Subnum
Subnum = 67
' Restore the user cursor if there is one
' It isn't safe to use LOCATE here, because we're in the user's underlying
' video mode, so we use a direct DOS BIOS call.
InterruptNumber% = &H10 ' ROM-BIOS Video Services Interrupt
AH% = &H01 ' Set Cursor Size
CL% = DOSCursorStop ' Set the user bottom scan line
CH% = DOSCursorStart ' Set the user top scan line
IF DOSCursorState THEN ' If cursor was on
CH% = CH% OR N32 ' turn on bit 5
ELSE
CH% = CH% AND NOT N32 ' else turn it off
END IF
GOSUB DOSBIOS
'
InterruptNumber% = &H10 ' ROM-BIOS Video Services Interrupt
AH% = &H02 ' Set Cursor Position function
BH% = DOSCursorPage ' Set the user video page
DH% = DOSCursorRow ' Set the user cursor row
DL% = DOSCursorColumn ' Set the user cursor column
GOSUB DOSBIOS
' Restore the state of the Insert, Caps, Num, and Scroll keys
CALL MhSetKbStatus(InsertDOS%, CapsDOS%, NumDOS%, ScrollDOS%)
Subnum = SubnumSave
EXIT SUB
DOSBIOS:
CALL DOSBIOSServices
RETURN
END SUB
'=========================================================================
SUB ReturnLine STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 68
CALL ReturnLineDelete
CALL ShowIt(N7, N24, N62, " Return ")
CALL ShowIt(N6, N0, Nm1, "Proceed")
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ReturnLineDelete STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 69
CALL ShowErase(N6, N24, N62, N19, Blank0$)
Subnum = SubnumSave
END SUB
'=========================================================================
SUB SaveCurrentDirectory (EntryPoint) STATIC
'=========================================================================
' Store User or Calendar's Current Directory
DEFINT A-Z
SubnumSave = Subnum
Subnum = 70
'-----------------------------------------------------------
' Get User or Calendar Directory
DirectoryGet$ = SPACE$(65)
DriveGet = N0
CALL MhDir(N1%, DriveGet%, DirectoryGet$, Ecode%)
IF Ecode THEN ERROR 255
'-------------------------------------------------------------------------
GetPath$ = RTRIM$(CHR$(N64 + DriveGet) + ":\" + ASCIIN$(DirectoryGet$))
DirectoryGet$ = ASCIIZ$(GetPath$)
'-------------------------------------------------------------------------
IF EntryPoint THEN
DriveReturn = DriveGet
DirectoryReturn$ = DirectoryGet$
ReturnPath$ = GetPath$
ELSE
DriveUser = DriveGet
DirectoryUser$ = DirectoryGet$
UserPath$ = GetPath$
END IF
Subnum = SubnumSave
END SUB
'=========================================================================
SUB SaveDOSKeyState STATIC
'=========================================================================
' Save DOS Keystate
DEFINT A-Z
SubnumSave = Subnum
Subnum = 71
'----------------------------------
' Determine number of display rows and columns
CALL MhDisplay (DispMode%, UserColumns%, UserRows%, Memory%, _
DisplayType%)
DisplayColumns = UserColumns
DisplayRows = UserRows
'----------------------------------
' Get the state of the insert, caps, num, and scroll keys
CALL MhGetKbStatus1(InsertDOS%, CapsDOS%, NumDOS%, ScrollDOS%, _
Alt%, Ctrl%, Left%, Right%)
'----------------------------------
' ROM-BIOS Video Services Interrupt
' Get Cursor, mode, and page Information
' First Determine the user's video page and mode.
InterruptNumber% = &H10 ' Video Services
AH% = &H0F ' Get User's Video Page and mode
GOSUB DOSBIOS2
UserMode = AL% ' Save user video mode
CurrentVideoMode = AL% ' and set it as current
DOSCursorPage = BH% ' Save user video page
CurrentVideoPage = BH% ' and set it as current
'----------------------------------
InterruptNumber% = &H10 ' Video Services
AH% = &H3 ' Read Cursor Information
GOSUB DOSBIOS2
' On return, this is what the registers contain:
' CH=Cursor start line, CL=Cursor end line
' DH=Cursor Row (base 0), DL=Cursor column (base 0)
'----------------------------------
DOSCursorRow = N1 + DH% ' Save user cursor row
DOSCursorColumn = N1 + DL% ' Save user cursor column
' Mask Cursor Start Scan Line Bits
DOSCursorStart = CH% AND N15 ' Save user cursor top scan line
DOSCursorStop = CL% ' Save user cursor bottom scan line
DOSCursorBit = CH% AND N32 ' Isolate user Cursor On/Off Bit
' Test for Cursor Off
IF DOSCursorBit = N32 THEN ' Save state of user cursor
DOSCursorState = N0
ELSE
DOSCursorState = N1
END IF
'----------------------------------
' This is the *only* safe place to turn the user cursor off, as we're
' in the underlying program's video mode and page, here. BASIC
' statements don't know anything about this mode and page, so we use
' direct DOS video functions to accomplish this.
AH% = &H01 ' Set Cursor Size function
CL% = DOSCursorStop ' turn user cursor off
CH% = DOSCursorStart
CH% = CH% AND NOT N32 ' and turn it off
GOSUB DOSBIOS2
'----------------------------------
DOSColor = SCREEN(N1, N1, N1) ' save DOS Colors
CALL ColorDecode(DOSColor) ' (not sure this is save in all
DOSForeground = ColorForeground ' modes, so looking into a replacement
DOSBackground = ColorBackground ' for the BASIC SCREEN function.)
'
Subnum = SubnumSave
EXIT SUB
DOSBIOS2:
CALL DOSBIOSServices
RETURN
END SUB
'=========================================================================
SUB ScreenBottoms STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 72
IF NOT NewGuy AND NOT SrAutoOptions THEN
CALL PopLine
END IF
CALL EscapeLine
CALL ReturnLine
CALL QuitLine
Subnum = SubnumSave
END SUB
'=========================================================================
SUB ScreenBottomsDelete STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 73
CALL PopLineDelete
CALL EscapeLineDelete
CALL ReturnLineDelete
Subnum = SubnumSave
END SUB
'=========================================================================
SUB SequenceEventsTable STATIC
'=========================================================================
' Resequence Event Table When Alarm Rings Or After Event Editing
DEFINT A-Z
SubnumSave = Subnum
Subnum = 65
IF EventTableStable THEN GOTO ExitPoint3
'-------------------------------------------------------------------------
NormalAlarmBuild:
' Read the Event List. Decide To Resequence Only If needed.
'-------------------------------------------------------------------------
IF ClockScreen THEN
RefreshInstructions = Yes
END IF
CALL ShowErase(N14, N25, N1, N80, SPACE$(N21) + _
"Please Wait--Building Alarm List")
SchCnt$ = Blank8$
RedisplayNotesEvents = Yes
EventsScheduled = N0
HeldDateTime# = 0#
Badrec = No
ExistingNullrec = No
TimerSave! = TIMER
'-------------------------------------------------------------------------
FOR WhichEvent = N1 TO NumberofEvents
CALL KeyStuff(KeyStatus)
CALL MhIntToString(SchCnt$, (NumberofEvents% + N1% - WhichEvent%))
CALL ShowIt(N14, N25, N60, SchCnt$)
'--------------------------------------------------------------------
' Blink Event Table Initialize
PendingEvents(WhichEvent) = N0
'--------------------------------------------------------------------
RecordPointer = N1 + WhichEvent
' Get Next Record--Sets Contents in CurrentEventRecord$
CALL GetApptRecord(RecordPointer)
'--------------------------------------------------------------------
' Test if Blanks In The Sequence--If So, Sets Resort Flag
IF CurrentEventRecord$ = Blank80$ THEN
ExistingNullrec = Yes
GOTO NextRecord
END IF
'--------------------------------------------------------------------
' Non-Blank Record
'--------------------------------------------------------------------
' Set Null Record If There Is One For Test
IF ExistingNullrec THEN
' There was a blank record in the middle of non-blank ones
Badrec = Yes
END IF
'--------------------------------------------------------------------
' Very Old file format didn't have the year
'Fill In "19" In Record For Dates Which Don't Already Have It
IF MID$(CurrentEventRecord$, N74, N2) = Blank2$ THEN
CALL Myd2(CurrentEventRecord$, N74, N2, "19")
END IF
'---------------------------------------------------------------
' Construct the Event Date/Time for Validation
CALL MhMidString(EventDateTime$, N1%, N2%, CurrentEventRecord$, N74%)
CALL MhMidString(EventDateTime$, N3%, N10%, CurrentEventRecord$, N1%)
'---------------------------------------------------------------
' Check for bad records (missing numerics, out of sequence)
IF NumberError(EventDateTime$) THEN
' Non-numeric and non-blank
' blank out, write history, set flag to resort
EventtoHistory = No
HistoryBuffer$ = CurrentEventRecord$
CALL WritetoHistory
CALL MhLset(ApptBuffer$, Blank80$)
CALL PutApptRecord(RecordPointer)
Badrec = Yes
GOTO NextRecord
END IF
'---------------------------------------------------------------
' Good Record, Go On
CombinedDateTime# = VAL(EventDateTime$)
IF CombinedDateTime# > 0# AND _
CombinedDateTime# < HeldDateTime# THEN
' Out-of-sequence but good record
Badrec = Yes
END IF
HeldDateTime# = CombinedDateTime#
'---------------------------------------------------------------
' Bump Next Valid Slot Number
EventsScheduled = EventsScheduled + N1
'---------------------------------------------------------------
' Save Alarm Value In That Slot
Alarms(EventsScheduled).Alarm = CombinedDateTime#
' In Case We Need To Sort, Save Appt File Position
Alarms(EventsScheduled).Sequence = WhichEvent
' Build Alarms(x).Warning
IF Pending THEN
' Skip warning and blink table if not desired
CALL ComputePendingValue(Alarms(EventsScheduled).Alarm, _
Alarms(EventsScheduled).Warning)
END IF
'---------------------------------------------------------------
' Cancel Automatic Pop Down if Alarm or Warning coming
IF ((Pending AND Alarms(WhichEvent).Warning <= CurrentDateTime#) OR _
(Alarms(WhichEvent).Alarm <= CurrentDateTime#)) AND _
SrAutoPopDown AND NOT SrAutoPopDownHappened THEN
'----------------------------------------------------------
SrAutoPopDownHappened = Yes
IF AutoStarted THEN
CALL MinorBeeper
CALL ShowIt(N15, N16, Nm2, _
" ... and Automatic Pop Down Has Been Requested, But Cancelled! ")
END IF
END IF
NextRecord:
'--------------------------------------------------------------------
NEXT
'-------------------------------------------------------------------------
' At this point, an Alarm List is built, with warning times if Pending
' is non-zero. If either blank records were found inbetween the good
' ones, or if the records contained bad data or were out of time
' sequence, the list is resorted and rewritten to the appt file. Else
' we get out here. Note that Alarms(I) may be more compressed than the
' state of the file; this would require sorting.
' In either case, EventsScheduled is solid at this point.
' Of course, there may be nothing to do also.
'-------------------------------------------------------------------------
IF NOT Badrec AND NOT EventsScheduled THEN
GOTO FinishedSequence
END IF
'-------------------------------------------------------------------------
StartSequencing:
'--------------------------------------------------------------------
' Sort Phase 1 -- Sort the Alarms(I) Array
'-------------------------------------------------------------------------
ExitKeys = No ' Keep Program from Exiting Prematurely
'-------------------------------------------------------------------------
IF EventsScheduled > N1 THEN ' Don't Sort Only One Event
'--------------------------------------------------------------------
' Sort the Alarms(I) Array. Note that this also sorts the warning
' values (.Warning) AND the appt file position records (.Sequence)
CALL ShowErase(N14, N25, N1, N80, (SPACE$(N21) + _
"Please Wait--Sorting Alarm List"))
'--------------------------------------------------------------------
' Use Microsoft's Incredibly Fast Sort Algorithm from QB 4.50
SortLow = N1
SortHigh = EventsScheduled
CALL QuickSort(SortLow, SortHigh) ' Sort Alarm Table
END IF
'--------------------------------------------------------------------
' Sort Phase 2 -- Build Temporary File of Sorted Events
'--------------------------------------------------------------------
' Open Temporary Event Hold File
CALL KillAFile(ApptFilename$ + ".cls") ' Start Fresh!
OPEN "R", #FilenumApptSort, ApptFilename$ + ".cls", N80
FIELD #FilenumApptSort, N80 AS TempApptBuffer$
'--------------------------------------------------------------------
CALL ShowErase(N14, N25, N1, N80, (SPACE$(N21) + _
"Please Wait--Building Sorted Events"))
SchCnt$ = Blank8$
EventPosition = N0
'--------------------------------------------------------------------
FOR I = N1 TO EventsScheduled
CALL MhIntToString(SchCnt$, (EventsScheduled% - I% + N1%))
CALL ShowIt(N14, N25, N60, SchCnt$)
' No point in doing KeyStuff When ExitKeys is Off--Slows Us Down
'---------------------------------------------------------------
' Get the old record
EventPosition = EventPosition + N1
GET #FilenumAppt, N1 + Alarms(I).Sequence
CALL MhLset(TempApptBuffer$, ApptBuffer$)
' Write it to the new position in the temporary file
PUT #FilenumApptSort, EventPosition
'---------------------------------------------------------------
NEXT
'--------------------------------------------------------------------
' Sort Phase 3 -- Rewrite Temporary File to Appointment File
'--------------------------------------------------------------------
CALL ShowErase(N14, N25, N1, N80, (SPACE$(N21) + _
"Please Wait--Resaving Event List"))
SchCnt$ = Blank8$
FOR I = N1 TO NumberofEvents
'--------------------------------------------------------------------
' Note that ENTIRE file is written, not just EventsScheduled
'---------------------------------------------------------------
CALL MhIntToString(SchCnt$, (NumberofEvents% - I% + N1%))
CALL ShowIt(N14, N25, N60, SchCnt$)
' Copy Sorted List Back to Appointment File
IF I <= EventsScheduled THEN
GET #FilenumApptSort, I
CALL MhLset(ApptBuffer$, TempApptBuffer$)
ELSE
CALL MhLset(ApptBuffer$, Blank80$)
END IF
CALL PutApptRecord(N1 + I)
NEXT
'--------------------------------------------------------------------
CLOSE #FilenumApptSort
CALL KillAFile(ApptFilename$ + ".cls")
'--------------------------------------------------------------------
' Done
'--------------------------------------------------------------------
FinishedSequence:
IF ClockScreen THEN
CALL Kolors(N3)
ELSEIF OnEditPage THEN
CALL Kolors(N5)
ELSE
CALL Kolors(N6)
END IF
CALL ShowIt(N0, N25, N1, Blank80$)
' Flush I/O Buffers for Safety By Closing and Opening File
CALL OpenAppts
EventTableStable = Yes
ExitKeys = Yes
ExitPoint3:
Subnum = SubnumSave
END SUB
'=========================================================================
SUB SetArrays STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 74
' Set/Change Definitions Based Upon Event Table Size
NumberofEvents = N20 * InString(ValidSizes$, EventSizeCode$)
IF NumberofEvents <> EventTableSize THEN
EventTableSize = NumberofEvents
EventTableStable = No
TimerSave! = TIMER
END IF
NumberofNotes = N20 * InString(ValidSizes$, NoteSizeCode$)
OldNumberEvents = NumberofEvents
OldNumberNotes = NumberofNotes
' Redefine Appt File Pointers
StartingNote = N2 + NumberofEvents
StartingHistory = N2 + NumberofEvents + NumberofNotes
Subnum = SubnumSave
END SUB
'=========================================================================
SUB SetColors STATIC
'=========================================================================
DEFINT A-Z
SubnumSave = Subnum
Subnum = 75
ColorError = N0
FOR ColorPair = N1 TO N7
' Initialize Screen With Current Colors
DetermineWhichPair:
SELECT CASE ColorPair
CASE 1
CALL Kolors(N1)
Csav1 = Cl1f
Csav2 = Cl1b
CASE 2
CALL Kolors(N2)
Csav1 = Cl2f
Csav2 = Cl2b
CASE 3
CALL Kolors(N3)
Csav1 = Cl3f
Csav2 = Cl3b
CASE N4
CALL Kolors(N4)
Csav1 = Cl4f
Csav2 = Cl4b
CASE N5
CALL Kolors(N5)
Csav1 = Cl5f
Csav2 = Cl5b
CASE 6
CALL Kolors(N6)
Csav1 = Cl6f
Csav2 = Cl6b
CASE 7
CALL Kolors(N7)
Csav1 = Chf
Csav2 = Chb
END SELECT
CALL ClearScreenNormal(N1)
ScreenTitles$(N1) = " Change " + ColorPairUses$(ColorPair) + _
" Color (Screen" + STR$(ColorPair) + " of 7)"
CALL Titles(Nm1)
IF ColorError THEN
CALL MajorBeeper
KolorSet = N18
GOSUB WarningOrBlanking
ColorError = N0
END IF
CALL ShowIt(N6, N23, N1, "(Note: 8-Color Monitors Show No ")
CALL ShowIt(N0, Nm1, N0, " Difference Between The 1st 8 ")
CALL ShowIt(N0, Nm1, N0, " And The 2nd 8 Foreground Colors)")
FOR ColorPairType = N1 TO N2
' Calculate Displacements Based On Which Color Is Being Changed
XCL = N16 + 35 * (ColorPairType - N1)
WhichColor = (ColorPair - N1) * N2 + ColorPairType
IF ColorPairType = N1 THEN
ListSize = N16
ELSE
ListSize = N8
END IF
' Fill 16 Color List for Foreground, 8 for Background
FOR Clist = N1 TO ListSize
MenuLines(Clist) = Colors$(Clist)
NEXT Clist
' Get Current Color Choice
' Store Currently Chosen Colors For Menu
SELECT CASE WhichColor
CASE 1
ColorChoices(WhichColor) = Cl1f
MenuColorBack = Cl1b
CASE 2
ColorChoices(WhichColor) = Cl1b
MenuColorBack = Cl1f
CASE 3
ColorChoices(WhichColor) = Cl2f
MenuColorBack = Cl2b
CASE N4
ColorChoices(WhichColor) = Cl2b
MenuColorBack = Cl2f
CASE N5
ColorChoices(WhichColor) = Cl3f
MenuColorBack = Cl3b
CASE 6
ColorChoices(WhichColor) = Cl3b
MenuColorBack = Cl3f
CASE 7
ColorChoices(WhichColor) = Cl4f
MenuColorBack = Cl4b
CASE N8
ColorChoices(WhichColor) = Cl4b
MenuColorBack = Cl4f
CASE N9
ColorChoices(WhichColor) = Cl5f
MenuColorBack = Cl5b
CASE N10
ColorChoices(WhichColor) = Cl5b
MenuColorBack = Cl5f
CASE N11
ColorChoices(WhichColor) = Cl6f
MenuColorBack = Cl6b
CASE N12
ColorChoices(WhichColor) = Cl6b
MenuColorBack = Cl6f
CASE N13
ColorChoices(WhichColor) = Chf
MenuColorBack = Chb
CASE N14
ColorChoices(WhichColor) = Chb
MenuColorBack = Chf
END SELECT
MenuColorFore = ColorChoices(WhichColor)
ColorForeground = MenuColorFore
ColorBackground = MenuColorBack
CALL Kolors(N0) ' Special Colors
CALL ShowIt(N0, N4, XCL + N1, (ColorPairTypes$(ColorPairType)))
' Display Menu For Change
MenuChoice = N1 + ColorChoices(WhichColor)
IF ColorPairType = N1 THEN
ColorSave1 = MenuChoice - N1
ELSE
ColorSave2 = MenuChoice - N1
END IF
CALL MenuDriver(ListSize, MenuChoice, N5, XCL, _
MenuSingleLine, N0, N1, N1)
ColorForeground = Csav1
ColorBackground = Csav2
KolorSet = N6
GOSUB WarningOrBlanking ' Delete Error Message
' Normal Out On Beginning of Pair
IF MenuExit = MenuCancelled AND ColorPairType = N1 THEN
GOTO RewriteColorFile
END IF
' Out Before End of Pair Compares With Previous Value
' Set the Changed Color
ColorChoices(WhichColor) = MenuChoice - N1
' Re-Establish Color Setting From Menu Choice
GOSUB SaveChangedColor
NEXT ColorPairType
' Reject Pairs Which Are Equal
ColorError = N0
IF ColorChoices(WhichColor) = ColorChoices(WhichColor - N1) THEN
ColorError = N1
ColorChoices(WhichColor) = ColorSave2
GOSUB SaveChangedColor
WhichColor = WhichColor - N1
ColorChoices(WhichColor) = ColorSave1
GOSUB SaveChangedColor
GOTO DetermineWhichPair
ELSEIF MenuExit = MenuCancelled THEN
EXIT FOR
END IF
NEXT ColorPair
RewriteColorFile:
WhichColor = N0
CALL WriteCalfig
CALL ClearScreenNormal(N1)
CALL DirectReturnCheck
GOTO ExitPoint4
' Rewrite
SaveChangedColor:
SELECT CASE WhichColor ' Save Changed Color From Menu
CASE 1
Cl1f = ColorChoices(WhichColor)
CASE 2
Cl1b = ColorChoices(WhichColor)
CASE 3
Cl2f = ColorChoices(WhichColor)
CASE N4
Cl2b = ColorChoices(WhichColor)
CASE 5
Cl3f = ColorChoices(WhichColor)
CASE 6
Cl3b = ColorChoices(WhichColor)
CASE 7
Cl4f = ColorChoices(WhichColor)
CASE N8
Cl4b = ColorChoices(WhichColor)
CASE N9
Cl5f = ColorChoices(WhichColor)
CASE N10
Cl5b = ColorChoices(WhichColor)
CASE N11
Cl6f = ColorChoices(WhichColor)
CASE N12
Cl6b = ColorChoices(WhichColor)
CASE N13
Chf = ColorChoices(WhichColor)
CASE N14
Chb = ColorChoices(WhichColor)
END SELECT
RETURN
'-------------------------------------------------------------------------
WarningOrBlanking:
CALL Kolors(KolorSet) ' Warning or blanking color
' Blank Error Area
CALL ShowMult(N0, N7, N62, N19, N4) ' Box for message or erase it
' Print Error Message
IF KolorSet <> N6 THEN
CALL ShowIt(N0, N0, N0, " Background and ")
CALL ShowIt(N0, Nm1, N0, " foreground colors ")
CALL ShowIt(N0, Nm1, N0, " must be different ")
CALL ShowIt(N0, Nm1, N0, " -- try again !! ")
END IF
RETURN
'-------------------------------------------------------------------------
ExitPoint4:
Subnum = SubnumSave
END SUB
'=========================================================================
SUB SetCurrentDirectory (EntryPoint) STATIC
'=========================================================================
' Sets Calendar's, User's, or Swap Path's Directory
DEFINT A-Z
SubnumSave = Subnum
Subnum = 76
'-------------------------------------------------------------------------
SELECT CASE EntryPoint
CASE 0 ' User's Directory
DirectorySet$ = DirectoryUser$
DriveSet = DriveUser
CASE 1 ' Calendar's Directory
DirectorySet$ = DirectoryReturn$
DriveSet = DriveReturn
CASE 2 ' Disk Swap Directory
DirectorySet$ = SrSwapPath$ + CHR$(N0)
DriveSet = InString(LEFT$(PathLegalChars$, N26), _
LEFT$(SrSwapPath$, N1))
END SELECT
CALL MhDir(N2%, DriveSet%, DirectorySet$, Ecode%) ' Set
IF Ecode AND EntryPoint <> N2 THEN
ERROR 255
END IF
Subnum = SubnumSave
END SUB ' Drive and Directory
'========================================================================
'======================== END OF CAL5.BAS =============================
'========================================================================